package com.mybatis.jpa.sqlbuilder.query.parser;

import com.mybatis.jpa.constants.ParamConstants;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PartTree {

//    private static final Pattern PREFIX_TEMPLATE = Pattern.compile("^(find|read|get|query|stream|count|exists|delete|remove)((\\p{Lu}.*?))??By");
    private static final Pattern PREFIX_TEMPLATE = Pattern.compile("^(find)((\\p{Lu}.*?))??By");

    private OrPart node;

    public PartTree(String source, Class<?> entityClass, Map<String, Object> paramMap) {
        Matcher matcher = PREFIX_TEMPLATE.matcher(source);
        if (matcher.find()) {
            node = new OrPart(source.substring(matcher.group().length()), entityClass, paramMap);
        }
    }

    private static String[] split(String text, String keyword) {
        Pattern pattern = Pattern.compile(String.format("(%s)(?=(\\p{Lu}|\\P{InBASIC_LATIN}))", keyword));
        return pattern.split(text);
    }

    public List<Part> list() {
        return node.getChildren();
    }

    private static class OrPart {
        private final List<Part> children = new ArrayList<>();

        public OrPart(String source, Class<?> entityClass, Map<String, Object> paramMap) {
            String[] split = PartTree.split(source, "And");
            for (int i = 0; i < split.length; i++) {
                String key = ParamConstants.MYBATIS_PARAM+ (i + 1);
                if (paramMap.containsKey(key)) {
                    children.add(new Part(split[i], entityClass, key, paramMap));
                } else {
                    int length = split.length;
                    throw new IllegalStateException(String.format("sql 语句需要%s个参数，实际入参不足%s个", length, length));
                }
            }
        }

        public List<Part> getChildren() {
            return children;
        }
    }
}
